import { createClient } from '@supabase/supabase-js' import { NextResponse } from 'next/server' import type { UpdateFileSystemItemRequest } from '@/lib/types/database' // Create server-side Supabase client with user session function createServerSupabaseClient(request: Request) { // Get the authorization header from the request const authHeader = request.headers.get('authorization') return createClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { auth: { autoRefreshToken: false, persistSession: false }, global: { headers: authHeader ? { Authorization: authHeader } : {} } } ) } // GET /api/books/[id]/files/[fileId] - Get a specific file export async function GET( request: Request, { params }: { params: { id: string; fileId: string } } ) { try { const supabase = createServerSupabaseClient(request) const bookId = params.id const fileId = params.fileId // Get the file system item (RLS will handle access control) const { data: item, error } = await supabase .from('file_system_items') .select('*') .eq('id', fileId) .eq('book_id', bookId) .single() if (error || !item) { return NextResponse.json( { error: 'File not found' }, { status: 404 } ) } return NextResponse.json({ item }) } catch (error) { console.error('Error in GET /api/books/[id]/files/[fileId]:', error) return NextResponse.json( { error: 'Internal server error' }, { status: 500 } ) } } // PUT /api/books/[id]/files/[fileId] - Update a file or folder export async function PUT( request: Request, { params }: { params: { id: string; fileId: string } } ) { try { const supabase = createServerSupabaseClient(request) const bookId = params.id const fileId = params.fileId const body: UpdateFileSystemItemRequest = await request.json() // Check if file exists (RLS will handle access control) const { data: existingItem, error: existingError } = await supabase .from('file_system_items') .select('*') .eq('id', fileId) .eq('book_id', bookId) .single() if (existingError || !existingItem) { return NextResponse.json( { error: 'File not found' }, { status: 404 } ) } // If moving to a new parent, validate parent exists and is a folder if (body.parent_id && body.parent_id !== existingItem.parent_id) { const { data: parent, error: parentError } = await supabase .from('file_system_items') .select('id, type') .eq('id', body.parent_id) .eq('book_id', bookId) .single() if (parentError || !parent) { return NextResponse.json( { error: 'Parent folder not found' }, { status: 400 } ) } if (parent.type !== 'folder') { return NextResponse.json( { error: 'Parent must be a folder' }, { status: 400 } ) } } // Prepare update data const updateData: any = {} if (body.name !== undefined) updateData.name = body.name if (body.content !== undefined) updateData.content = body.content if (body.expanded !== undefined) updateData.expanded = body.expanded if (body.sort_order !== undefined) updateData.sort_order = body.sort_order if (body.parent_id !== undefined) updateData.parent_id = body.parent_id // Update the item const { data: updatedItem, error } = await supabase .from('file_system_items') .update(updateData) .eq('id', fileId) .eq('book_id', bookId) .select() .single() if (error) { console.error('Error updating file system item:', error) return NextResponse.json( { error: 'Failed to update item' }, { status: 500 } ) } return NextResponse.json({ item: updatedItem, message: 'Item updated successfully' }) } catch (error) { console.error('Error in PUT /api/books/[id]/files/[fileId]:', error) return NextResponse.json( { error: 'Internal server error' }, { status: 500 } ) } } // DELETE /api/books/[id]/files/[fileId] - Delete a file or folder export async function DELETE( request: Request, { params }: { params: { id: string; fileId: string } } ) { try { const supabase = createServerSupabaseClient(request) const bookId = params.id const fileId = params.fileId // Check if item exists (RLS will handle access control) const { data: existingItem, error: existingError } = await supabase .from('file_system_items') .select('id, type, name') .eq('id', fileId) .eq('book_id', bookId) .single() if (existingError || !existingItem) { return NextResponse.json( { error: 'Item not found' }, { status: 404 } ) } // Delete the item - CASCADE DELETE will handle children automatically const { error: deleteError } = await supabase .from('file_system_items') .delete() .eq('id', fileId) .eq('book_id', bookId) if (deleteError) { console.error('Error deleting file system item:', deleteError) return NextResponse.json( { error: 'Failed to delete item' }, { status: 500 } ) } return NextResponse.json({ message: `${existingItem.type === 'file' ? 'File' : 'Folder'} deleted successfully` }) } catch (error) { console.error('Error in DELETE /api/books/[id]/files/[fileId]:', error) return NextResponse.json( { error: error instanceof Error ? error.message : 'Internal server error' }, { status: 500 } ) } }